#pragma once
#include <cerrno>
#include <cstdint>
#include <cstring>
#include<iostream>
#include <memory>
#include <string>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include "ThreadPool/Log.hpp"
#include"ThreadPool/ThreadPool.hpp"
#include"ThreadPool/Task.hpp"

class TcpServer
{
public:
    TcpServer(uint16_t port,std::string ip="")
    :_ip(ip),_port(port)
    ,_sock(-1)
    {

    }
    bool initServer()
    {
        _sock=socket(AF_INET, SOCK_DGRAM, 0);
        if(_sock < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(1);
        }
        struct sockaddr_in server;
        bzero(&server,sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(_port);
        server.sin_addr.s_addr=inet_addr(_ip.c_str());
        if(bind(_sock, (struct sockaddr*)&server, sizeof(server)) < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(2);
        }
        logMessage(NORMAL, "bind() succeed");
        if(listen(_sock, gbackLog) < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(3);
        }
        logMessage(NORMAL, "listen() succeed");
    }
    void start()
    {
        //一个简单的单线程版本就写好了
        thread_ptr->run();
        while(true)
        {
            struct sockaddr_in server;
            socklen_t len=sizeof(server);
            int serversock=accept(_sock, (struct sockaddr*)&server, &len);
            if(serversock < 0)
            {
                logMessage(FATAL, "%d:%s",errno,strerror(errno));
                exit(1);
            }
            uint16_t serverport=ntohs(server.sin_port);
            std::string serverip=inet_ntoa(server.sin_addr);
            Task task;
            thread_ptr->pushTask(task);
        }
    }
    ~TcpServer(){

    }
private:
    const int gbackLog=20;
    uint16_t _port;
    std::string _ip;
    int _sock;
    std::unique_ptr<ThreadPool<Task>> thread_ptr;
};
